/*
 * Copyright 2021. Huawei Technologies Co., Ltd. All rights reserved.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

 */

package com.bei.lingluan.hwid;

import com.huawei.hms.accountsdk.constant.CommonConstant;
import com.huawei.hms.accountsdk.exception.ApiException;
import com.huawei.hms.accountsdk.support.account.AccountAuthManager;
import com.huawei.hms.accountsdk.support.account.request.AccountAuthParams;
import com.huawei.hms.accountsdk.support.account.request.AccountAuthParamsHelper;
import com.huawei.hms.accountsdk.support.account.result.AuthAccount;
import com.huawei.hms.accountsdk.support.account.service.AccountAuthService;
import com.huawei.hms.accountsdk.support.account.tasks.OnFailureListener;
import com.huawei.hms.accountsdk.support.account.tasks.OnSuccessListener;
import com.huawei.hms.accountsdk.support.account.tasks.Task;
import ohos.aafwk.ability.AbilityPackage;

/**
 * @author 北海
 * @version 1.0
 * @description
 * @date 2022/2/11
 */

public final class HuaweiAccountSDKProxy {
    // 用来更新界面的present接口类
    private HwidPresent hwidPresent;

    public HuaweiAccountSDKProxy() {
        super();
    }

    public HuaweiAccountSDKProxy(HwidPresent hwidPresent) {
        super();
        this.hwidPresent = hwidPresent;
    }

    /**
     * 调用华为帐号SDK的初始化方法AccountAuthManager.init()进行初始化
     * @param abilityPackage
     */
    public void initHuaweiAccountSDK(AbilityPackage abilityPackage) {
        Task<Void> task;
        try {
            //showInfo("InitHuaweiAccountSDK Start");
            // 调用AccountAuthManager.init方法初始化
            task = AccountAuthManager.init(abilityPackage);
        } catch (ApiException apiException) {
            showInfo("InitHuaweiAccountSDK exception: "
                    + apiException.getStatusCode()
                    + "; message: "
                    + apiException.getStatusMessage());
            apiException.getStatusCode();
            return;
        }
        task.addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void v) {
                //初始化成功
                showInfo("initHuaweiAccountSDK SUCCESS.");
            }
        });

        task.addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                // SDK初始化失败
                if (e instanceof ApiException) {
                    ApiException apiException = (ApiException) e;
                    // SDK初始化失败，status code标识了失败的原因
                    apiException.getStatusCode();
                    showInfo("InitHuaweiAccountSDK FAILED. statusCode: "
                            + apiException.getStatusCode()
                            + "; message: "
                            + apiException.getStatusMessage());
                }
            }
        });
    }

    /**
     * 华为账号登录
     */
    public void signIn() {
        showInfo("Init Huawei account auth service START.");
        AccountAuthService accountAuthService;
        //配置登录请求参数AccountAuthParams
        AccountAuthParams accountAuthParams = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
                .setEmail()
                .createParams();
        try {
            accountAuthService = AccountAuthManager.getService(accountAuthParams);
        } catch (ApiException e) {
            // 处理初始化登录授权服务失败
            e.getStatusCode();
            showInfo("Init Huawei accountAuthService FAILED.");
            return;
        }
        //showInfo("Init Huawei accountAuthService SUCCESS");

        // 调用静默登录接口。
        Task<AuthAccount> taskSilentSignIn = accountAuthService.silentSignIn();
        showInfo("SilentSign START.");
        // 添加静默登录成功处理监听
        taskSilentSignIn.addOnSuccessListener(new OnSuccessListener<AuthAccount>() {
            @Override
            public void onSuccess(AuthAccount authAccount) {
                showInfo("SilentSignIn SUCCESS");
                tip("登录成功");
                // 静默登录成功后，根据结果中获取到的帐号基本信息更新UI
                updateUI(authAccount);
            }
        });
        // 添加静默登录失败监听
        taskSilentSignIn.addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                if (e instanceof ApiException) {
                    ApiException apiException = (ApiException) e;
                    showInfo("SilentSignIn FAILED, status code: " + apiException.getStatusCode() + ". Need to foreground sign in");

                    // 静默登录失败，显式地调用前台登录授权接口，完成登录授权。
                    Task<AuthAccount> taskSignIn = accountAuthService.signIn();
                    showInfo("SignIn foreground START.");
                    if (taskSignIn == null) {
                        showInfo("SignIn foreground task is null.");
                        return;
                    }
                    taskSignIn.addOnSuccessListener(new OnSuccessListener<AuthAccount>() {
                        @Override
                        public void onSuccess(AuthAccount result) {
                            showInfo("SignIn foreground SUCCESS.");
                            tip("登录成功");
                            updateUI(result);
                        }
                    });
                    taskSignIn.addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(Exception e) {
                            showInfo("SignIn foreground FAILED.");
                            if (e instanceof ApiException) {
                                ApiException apiException = (ApiException) e;
                                // 登录失败
                                apiException.getStatusCode();
                                showInfo("SignIn foreground FAILED. status code: "
                                        + apiException.getStatusCode()
                                        + ".");
                                if (CommonConstant.RETCODE.SIGN_IN_CANCELLED == apiException.getStatusCode()) {
                                    showInfo("Error message: User click CANCEL or Return, user cancel login in.");
                                }
                            }
                        }
                    });
                }
            }
        });
    }

    /**
     * 华为帐号登出
     */
    public void signOut() {
        AccountAuthService accountAuthService = null;
        AccountAuthParams accountAuthParams = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
                .setEmail()
                .createParams();
        try {
            accountAuthService = AccountAuthManager.getService(accountAuthParams);
        } catch (ApiException apiException) {
            // 处理初始化登录授权服务失败
            apiException.getStatusCode();
            showInfo("Account service init FAILED. status code: " + apiException.getStatusCode());
            return;
        }

        Task<Void> task = accountAuthService.signOut();
        task.addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void v) {
                // 华为帐号登出成功，接入应用处理登出后逻辑
                showInfo("Account sign out SUCCESS.");
                tip("登出成功");
                refresh();
            }
        });
        task.addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                // 华为帐号登出失败
                if (e instanceof ApiException) {
                    ApiException apiException = (ApiException) e;
                    // 华为帐号登出失败
                    apiException.getStatusCode();
                    showInfo("Account sign out FAILED. status code: " + apiException.getStatusCode());
                }
            }
        });
    }

    /**
     * 华为帐号取消授权，取消授权后，再次静默登录将拉起授权页面
     */
    public void cancelAuthorization() {
        AccountAuthService accountAuthService;
        AccountAuthParams accountAuthParams = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
                .setEmail()
                .createParams();
        try {
            accountAuthService = AccountAuthManager.getService(accountAuthParams);
        } catch (ApiException e) {
            // 处理初始化登录授权服务失败，status code标识了失败的原因
            e.getStatusCode();
            return;
        }
        // 调用取消授权接口
        Task<Void> task = accountAuthService.cancelAuthorization();
        task.addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void v) {
                // 取消授权成功
                showInfo("Cancel authorization SUCCESS.");
                tip("取消授权成功");
                refresh();
            }
        });

        task.addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(Exception e) {
                // 取消授权失败
                if (e instanceof ApiException) {
                    ApiException apiException = (ApiException) e;
                    // 华为帐号取消授权失败，status code标识了失败的原因
                    apiException.getStatusCode();
                    showInfo("Cancel authorization FAILED. status code: " + apiException.getStatusCode());
                }
            }
        });
    }

    private void updateUI(AuthAccount account) {
        if (hwidPresent != null) {
            hwidPresent.updateUI(account);
        }
    }

    private void showInfo(String info) {
        if (hwidPresent != null) {
            hwidPresent.showInfo(info);
        }
    }

    private void tip(String info) {
        if (hwidPresent != null) {
            hwidPresent.tip(info);
        }
    }

    private void refresh(){
        if (hwidPresent != null) {
            hwidPresent.refresh();
        }
    }

}
